package com.ujoku.controller;

import com.labillusion.core.platform.exception.ResourceNotFoundException;
import com.labillusion.core.platform.web.pagination.PaginationForm;
import com.labillusion.core.platform.web.rest.RESTController;
import com.labillusion.core.platform.web.rest.exception.InvalidRequestException;
import com.labillusion.core.util.UUIDUtils;
import com.ujoku.context.ActionContext;
import com.ujoku.context.constants.ContextConstants;
import com.ujoku.context.constants.StatusConstants;
import com.ujoku.domain.*;
import com.ujoku.domain.admin.Parameter;
import com.ujoku.interceptor.LoginRequired;
import com.ujoku.request.MyListForm;
import com.ujoku.request.MyListItemOnSaleForm;
import com.ujoku.request.MyListRepurchaseForm;
import com.ujoku.service.*;
import com.ujoku.service.admin.ParametersService;
import com.ujoku.view.domain.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@RestController
public class MyListController extends RESTController {

    private final Logger logger = LoggerFactory.getLogger(MyListController.class);

    @Autowired
    private ActionContext actionContext;

    @Autowired
    private MyListService myListService;

    @Autowired
    private MyListItemService myListItemService;

    @Autowired
    private RepurchaseItemService repurchaseItemService;

    @Autowired
    private CdnService cdnService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private ParametersService parametersService;

    @Autowired
    private ApplyService applyService;

    @RequestMapping(value="/myList", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public MyListView getMyList(@RequestBody @Valid MyListForm form) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());
        MyListView myListView = new MyListView();

        if(myList != null)
        {
            int totalCount= myListService.getItemCount(form, myList);
            int onSaleCount = myListService.getItemOnSaleCount(form, myList);
            int repurchaseItemCount = myListService.getRepurchaseItemCount(form, myList);

            //构造分页项
            Map<String,Object> query = form.getQueryMap();
            query.put("myListId", myList.getId());
            query.put("onSale", form.isOnSale());
            int count = myListItemService.selectCount(query);
            myList.setMyListItemList(myListItemService.selectList(query));

            myListView.setMyList(myList);
            myListView.setCount(count);
            myListView.setOnSaleCount(onSaleCount);
            myListView.setTotalCount(totalCount);
            myListView.setRepurchaseCount(repurchaseItemCount);

        }else{
            myListView.setMyList(new MyList());
            myListView.setCount(0);
            myListView.setOnSaleCount(0);
            myListView.setTotalCount(0);
            myListView.setRepurchaseCount(0);
        }
        int friendCount = myListService.getFriendCount(form, member);
        myListView.setFriendCount(friendCount);

        myListView.setMember(member);
        return myListView;
    }


    //查看他人私人酒窖产品
    @RequestMapping(value="/cellar", method = RequestMethod.POST)
    @ResponseBody
    public CellarView getCellar(@RequestBody @Valid MyListForm form,HttpServletRequest request) {
        if(form.getMemberId() == null || form.getMemberId() <= 0)
            throw new InvalidRequestException("memberId invalid");

        Member member = (Member) memberService.selectById(form.getMemberId());
        if(member == null)
            throw new ResourceNotFoundException("can not found memebr");

        CellarView cellarView = new CellarView();
        MyList myList = myListService.selectOnlyMyListByMemberId(member.getUser_id());;

        Member login = actionContext.getMember();
        if(myList != null)
        {
            int totalCount= myListService.getItemCount(form, myList);
            int onSaleCount = myListService.getItemOnSaleCount(form, myList);
            //构造分页项
            Map<String,Object> query = form.getQueryMap();
            query.put("myListId", myList.getId());
            query.put("onSale", form.isOnSale());
            query.put("inStock", true);
            int count = myListItemService.selectCount(query);
            List<MyListItem> list = myListItemService.selectList(query);

            if(login != null){
                Map<String,Object> temp = new HashMap<>();
                temp.put("fromMemberId",login.getUser_id());
                temp.put("toMemberId",member.getUser_id());
                Apply apply;
                for(MyListItem item : list){
                    temp.put("listItemId", item.getId());
                    apply = (Apply)applyService.selectOne(temp);
                    if(apply !=null)
                        item.setApplyId(apply.getId());
                }
            }

            myList.setMyListItemList(list);

            cellarView.setMyList(myList);
            cellarView.setCount(count);
            cellarView.setOnSaleCount(onSaleCount);
            cellarView.setTotalCount(totalCount);
            cellarView.setFriendCount(member.getFriendCount());
        }

        if(login != null){
            //查看是否为好友
            Map<String, Object> myFriendQuery = new HashMap<>();
            myFriendQuery.put("memberId", login.getUser_id());
            List<Member> myFriendListList = memberService.getMyFriendList(myFriendQuery);
            cellarView.setMyFriend(myFriendListList.stream().anyMatch(m->m.getUser_id() == member.getUser_id()));
        }

        FriendView friendView = new FriendView();
        memberService.setMemberPortrait(member,request);
        BeanUtils.copyProperties(member,friendView);

        Parameter p = parametersService.getParameterByKey(ContextConstants.MEMBER_LEVEL + member.getLevel());
        if (p != null) {
            friendView.setLevelName(p.getMark());
        }

        cellarView.setFriendView(friendView);
        return cellarView;
    }

    @RequestMapping(value="/myListItem/{id}", method = RequestMethod.GET)
    @ResponseBody
    @LoginRequired
    public MyListItem getMyListItem(@PathVariable String id) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());
        if(myList == null)
            throw new ResourceNotFoundException("can not found myList");

        MyListItem myListItem = myListItemService.selectOneMyListItem(myList.getId(),id);
        if(myListItem == null)
            throw new ResourceNotFoundException("can not found myList item");

        return myListItem;
    }

    @RequestMapping(value="/myList/sale", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public String sale(@RequestBody @Valid MyListItemOnSaleForm form) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());
        if(myList == null)
            throw new ResourceNotFoundException("can not found myList");

        MyListItem myListItem = myListItemService.selectOneMyListItem(myList.getId(), form.getMyListItemId());
        if(myListItem == null)
            throw new ResourceNotFoundException("can not found myList item");

        if(form.getOnSale() && myListItem.getOnSale()){
            throw new InvalidRequestException("current item has on sale");
        }

        if(form.getOnSale())
        {
            if(form.getPrice() == null || form.getPrice() <= 0){
                throw new InvalidRequestException("price","price invalid");
            }
            myListItem.setPrice(form.getPrice());
        }
        myListItem.setOnSale(form.getOnSale());

        myListItemService.update(myListItem);
        //更新销售数量
        updateMemberSaleCount(member, myList);

        return "success";
    }

    private void updateMemberSaleCount(Member member, MyList myList) {
        Map<String,Object> query = new HashMap<>();
        query.put("myListId", myList.getId());
        query.put("onSale", true);
        int count = myListItemService.selectCount(query);
        member.setOnSaleCount(count);
        actionContext.setMember(member);
        memberService.update(member);
    }

    @RequestMapping(value="/myList/p/{id}", method = RequestMethod.GET)
    @ResponseBody
    public MyListSaleView sale(@PathVariable String id) {
        Map<String,Object> query = new HashMap<>();
        query.put("goodsId",id);
        query.put("onSale", true);
        query.put("inStock", true);
        Integer memberId = actionContext.getCurrentVisitor().getUser_id();
        if(memberId != null)
            query.put("excludedMemberId",memberId);

        List<MyListItem> myListItemList = myListItemService.selectList(query);
        if(myListItemList.size() == 0)
            throw new ResourceNotFoundException("can not found mylist item");

        MyListSaleView view = new MyListSaleView();
        view.setMyMemberId(memberId);
        view.setList(new ArrayList<>());
        myListItemList.forEach(i->{
            MyListSaleItem saleItem = new MyListSaleItem();
            saleItem.setGoodsId(i.getGoodsId());
            saleItem.setGoodsName(i.getGoodsName());
            saleItem.setMediumImage(cdnService.buildGoodsImage(i.getGoodsId(), CdnService.Goods_Medium, i.getGoodsUpdateTime().getTime()));
            saleItem.setSmallImage(cdnService.buildGoodsImage(i.getGoodsId(), CdnService.Goods_Small, i.getGoodsUpdateTime().getTime()));
            saleItem.setMemberId(i.getMemberId());
            saleItem.setMemberName(i.getMemberName());
            saleItem.setMyListItemId(i.getId());
            saleItem.setPrice(i.getPrice());
            saleItem.setHeadPortraitUrl(memberService.getMemberPortrait(i.isPortrait(),i.getMemberId(),i.getPortraitUpdateTime()));
            view.getList().add(saleItem);

        });

        return view;
    }

    @RequestMapping(value="/myList/repurchase", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public String repurchase(@RequestBody @Valid MyListRepurchaseForm form) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());
        if(myList == null)
            throw new ResourceNotFoundException("can not found myList");

        MyListItem myListItem = myListItemService.selectOneMyListItem(myList.getId(), form.getMyListItemId());
        if(myListItem == null || myListItem.getOnSale())
            throw new ResourceNotFoundException("can not found myList item");

        if(form.getQty() == 0 || form.getQty() > myListItem.getQty()){
            throw new InvalidRequestException("qty","没有足够的数量");
        }

        if(myListItem.getQty() == form.getQty()){
            myListItem.setQty(0);
            myListItem.setStatus(StatusConstants.InActive);
        }
        else{
            myListItem.setQty(myListItem.getQty() - form.getQty());
        }

        myListItemService.update(myListItem);

        RepurchaseItem repurchaseItem = new RepurchaseItem();
        repurchaseItem.setId(UUIDUtils.random());
        repurchaseItem.setMemberId(member.getUser_id());
        repurchaseItem.setQty(form.getQty());
        repurchaseItem.setGoodsId(myListItem.getGoodsId());
        repurchaseItem.setGoodsName(myListItem.getGoodsName());
        repurchaseItem.setMyListId(myListItem.getMyListId());
        repurchaseItem.setMyListItemId(myListItem.getId());
        repurchaseItemService.insert(repurchaseItem);

        updateMemberSaleCount(member,myList);

        return "success";
    }

    @RequestMapping(value="/myList/repurchase/list", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public RepurchaseItemView repurchaseList(@RequestBody @Valid PaginationForm form) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());

        List<RepurchaseItem> list = new ArrayList<>();
        int totalCount = 0;
        int onSaleCount =0;
        int repurchaseItemCount = 0;
        int friendCount = 0;
        int count = 0;
        if(myList != null) {

            Map<String, Object> query = form.getQueryMap();
            query.put("myListId", myList.getId());

            totalCount = myListService.getItemCount(form, myList);
            onSaleCount = myListService.getItemOnSaleCount(form, myList);
            repurchaseItemCount = myListService.getRepurchaseItemCount(form, myList);
            friendCount = myListService.getFriendCount(form, member);
            count = repurchaseItemService.selectCount(query);


            list = repurchaseItemService.selectList(query);
            list.forEach(i -> i.setMediumImage(cdnService.buildGoodsImage(i.getGoodsId(), CdnService.Goods_Medium, i.getGoodsUpdateTime().getTime())));
        }
        RepurchaseItemView repurchaseItemView = new RepurchaseItemView();
        repurchaseItemView.setCount(count);
        repurchaseItemView.setOnSaleCount(onSaleCount);
        repurchaseItemView.setTotalCount(totalCount);
        repurchaseItemView.setRepurchaseCount(repurchaseItemCount);
        repurchaseItemView.setList(list);
        repurchaseItemView.setMember(member);
        repurchaseItemView.setFriendCount(friendCount);
        return repurchaseItemView;
    }

    @RequestMapping(value="/myList/repurchase/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    @LoginRequired
    public String cancelRepurchase(@PathVariable @Valid String id) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());
        if(myList == null)
            throw new ResourceNotFoundException("can not found myList");

        RepurchaseItem repurchaseItem = repurchaseItemService.selectOneRepurchaseItemItem(myList.getId(), id);
        if(repurchaseItem == null)
            throw new ResourceNotFoundException("can not found repurchaseItem");

        MyListItem myListItem = (MyListItem) myListItemService.selectById(repurchaseItem.getMyListItemId());

        if(myListItem == null)
            throw new ResourceNotFoundException("can not found myListItem");

        myListItem.setStatus(StatusConstants.Active);
        myListItem.setQty(myListItem.getQty() + repurchaseItem.getQty());
        myListItemService.update(myListItem);

        repurchaseItem.setStatus(RepurchaseStatus.CANCEL);
        repurchaseItemService.update(repurchaseItem);
        return "success";
    }

    @RequestMapping(value="/myList/repurchase/confirm/{id}", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public String confirmRepurchase(@PathVariable @Valid String id) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());
        if(myList == null)
            throw new ResourceNotFoundException("can not found myList");

        RepurchaseItem repurchaseItem = repurchaseItemService.selectOneRepurchaseItemItem(myList.getId(), id);
        if(repurchaseItem == null)
            throw new ResourceNotFoundException("can not found repurchaseItem");

        if(repurchaseItem.getStatus() != RepurchaseStatus.PRICE_CONFIRM)
            throw new ResourceNotFoundException("can not found repurchaseItem");

        if(repurchaseItem.getPrice() == null || repurchaseItem.getPrice() <=0){
            throw new ResourceNotFoundException("invalid repurchase item");
        }

        member.setBalance(member.getBalance() + repurchaseItem.getQty() * repurchaseItem.getPrice());
        memberService.update(member);
        actionContext.setMember(member);

        repurchaseItem.setStatus(RepurchaseStatus.FINISHED);
        repurchaseItemService.update(repurchaseItem);

        return "success";
    }

    @RequestMapping(value="/myList/friend/list", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public MyListFriendItemView friendItemList(@RequestBody @Valid PaginationForm form) {
        Member member = actionContext.getMember();
        MyList myList =  myListService.selectOnlyMyListByMemberId(member.getUser_id());

        int totalCount;
        int onSaleCount;
        int repurchaseItemCount;
        if(myList == null){
            totalCount = onSaleCount = repurchaseItemCount = 0;
        }else{
            totalCount= myListService.getItemCount(form, myList);
            onSaleCount = myListService.getItemOnSaleCount(form, myList);
            repurchaseItemCount = myListService.getRepurchaseItemCount(form, myList);
        }

        Map<String,Object> query = form.getQueryMap();
        query.put("memberId", member.getUser_id());
        int count = myListService.getFriendCount(form, member);
        if(count == 0)
            throw new ResourceNotFoundException("can not found friend Item");

        List<MyListItem> myListItemList = myListItemService.selectFriendItemList(query);

        MyListFriendItemView myListFriendItemView = new MyListFriendItemView();
        myListFriendItemView.setCount(count);
        myListFriendItemView.setOnSaleCount(onSaleCount);
        myListFriendItemView.setTotalCount(totalCount);
        myListFriendItemView.setRepurchaseCount(repurchaseItemCount);
        myListFriendItemView.setFriendCount(count);
        myListFriendItemView.setMember(member);

        for(MyListItem item : myListItemList){
            if(myListFriendItemView.getList().stream().anyMatch(i->i.getGoodsId() == item.getGoodsId())){
                continue;
            }
            //产品信息
            MyListFriendItem friendItem = new MyListFriendItem();
            friendItem.setGoodsId(item.getGoodsId());
            friendItem.setGoodsName(item.getGoodsName());
            friendItem.setPrice(item.getPrice());
            friendItem.setMediumImage(cdnService.buildGoodsImage(item.getGoodsId(), CdnService.Goods_Medium, item.getGoodsUpdateTime().getTime()));

            List<MyListItem> friendSourceList = myListItemList.stream().filter(i->i.getGoodsId() == item.getGoodsId()).collect(Collectors.toList());
            //好友列表
            List<MyListFriendView> friendList = new ArrayList<>();
            friendSourceList.forEach(f->{
                MyListFriendView friendView = new MyListFriendView();
                friendView.setFriendId(f.getFriendId());
                friendView.setFriendName(f.getFriendName());
                friendView.setMyListItemId(f.getId());
                friendView.setPrice(f.getPrice());
                friendView.setQty(f.getQty());
                friendView.setHeadPortraitUrl(memberService.getMemberPortrait(f.isPortrait(),f.getFriendId(),f.getPortraitUpdateTime()));
                friendList.add(friendView);
            });
            //找到最小价格
            MyListItem minItem = friendSourceList.stream().min((p1, p2) -> (p1.getPrice().compareTo(p2.getPrice()))).get();
            friendItem.setMinPrice(minItem.getPrice());
            MyListItem maxItem = friendSourceList.stream().max((p1, p2) -> (p1.getPrice().compareTo(p2.getPrice()))).get();
            //找打最大价格
            if(maxItem.getPrice().compareTo(minItem.getPrice()) > 0)
                friendItem.setMaxPrice(maxItem.getPrice());

            friendItem.setFriendList(friendList);
            myListFriendItemView.getList().add(friendItem);
        }

        return myListFriendItemView;
    }
}